package hexui.components;

import hexgame.HexGame;
import hexgame.HexGameRequest;
import hexgame.PlayMethods;
import hexgame.PlayerFactory;
import hexui.CheckForEndedGames;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.Timer;

import javax.swing.*;

import program.GameManager;

import network.HexNetwork;
import network.NetworkErrorException;
import network.NetworkPartialClientException;

public class ServerPanel extends JPanel{
	private static final long serialVersionUID = 1L;
	
	int port;
	Timer timer;
	CheckForEndedGames checkForEndedGames;
	Map<String, PlayerFactory> methods;
	GridBagLayout gridBagLayout;
	JLabel listeningOnPort;
	JLabel responsWith;
	JButton quit;
	JComboBox<String> players;
	
	
	public ServerPanel(int port) {
		this.port = port;
		
		this.gridBagLayout = new GridBagLayout();
		this.setLayout(gridBagLayout);
		
		methods = PlayMethods.getMethods();
		String[] playMethods = methods.keySet().toArray(new String[methods.size()]);
		
		this.listeningOnPort = new JLabel("Listening on port " + port);
		this.responsWith = new JLabel("Respond with:");
		this.players = new JComboBox<String> (playMethods);
		this.quit = new JButton("Quit");
		this.setComponents();
	}
	
	public void setComponents() {
		GridBagConstraints gc = new GridBagConstraints();
		
		gc.anchor = GridBagConstraints.NORTHWEST;
		gc.weightx = 0.1;
		gc.weighty = 0.2;
		gc.insets = new Insets(6, 10, 12, 10);
		gc.gridx = 0;
		gc.gridy = 0;
		gc.gridwidth = 2;
		this.add(listeningOnPort, gc);
		
		gc.gridwidth = 1;
		gc.gridx = 0;
		gc.gridy = 1;
		this.add(responsWith, gc);
		
		gc.gridx = 1;
		gc.gridy = 1;
		this.add(players, gc);
		
		gc.anchor = GridBagConstraints.SOUTHEAST;
		gc.insets = new Insets(6, 10, 6, 10);
		gc.gridx = 1;
		gc.gridy = 2;
		quit.addActionListener(new QuitListener());
		this.add(quit, gc);
	}
	
	public void listenForRequest() {
		this.initTimer();
		
		boolean quitLoop = false;
		HexNetwork network = null;
		try {
			network = new HexNetwork(port);
		}
		catch (NetworkErrorException e1) {
			System.out.println("Unable to start listening for games.");
			// Don't perform main listening loop
			quitLoop = true;
		}
		
		while(!quitLoop) {
			try {
				HexGameRequest request = network.getClient();
				request.setLocalPlayerFactory(methods.get(players.getSelectedItem()));
				HexGame game = new HexGame(request);
				game.startGame();
				GameManager.addGame(game);
			}
			catch(NetworkPartialClientException e) {
				System.out.println("A non-fatal error occured whilst retrieving a client. Continuing to listen");
			}
			catch(NetworkErrorException e) {
				System.out.println("A fatal error occured whilst listening for a client. " + e.getMessage());
				quitLoop = true;
			}
		}
		GameManager gameManager = new GameManager();
		gameManager.scheduleWindowGameCheck(new CheckForEndedGames());
	}
	
	private void initTimer() {
		timer = new Timer();
		checkForEndedGames = new CheckForEndedGames();
		timer.schedule(checkForEndedGames, 0, 2000);
	}
	
	class QuitListener implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
		
	}

}
